﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;

namespace QzgfFrame.Utility.Core.Import
{
    public class ImportFromPoiExcel : ImportFacade
    {
        protected log4net.ILog Logger = log4net.LogManager.GetLogger("ImportFromPoiExcel");
        // 文件类型
        private string filetype;
        // 当前的Sheet
        private int currSheet;
        // 当前位置
        private int currPosition;
        // Sheet数量
        private int numOfSheets;
        // HSSFWorkbook
        private HSSFWorkbook workbook = null;

        //将每行记录存入HashMap中
        private Hashtable headHash = new Hashtable(); //头部HashMap

        private String[] columnsvalue;
        private String[] fieldsvalue;
        // 构造函数创建一个ExcelReader
        public void Init(string inputfile, string[] columns, string[] Fields)
        {
            // 判断参数是否为空或没有意义
            if (inputfile == null || inputfile.Trim().Equals(""))
            {
                throw new IOException("no input file specified");
            }
            //初始化行头与列头
            columnsvalue = columns;
            fieldsvalue = Fields;
            // 取得文件名的后缀名赋值给filetype
            this.filetype = inputfile.Substring(inputfile.LastIndexOf(".") + 1);
            // 设置开始行为0
            currPosition = 0;
            // 设置当前位置为0
            currSheet = 0;
            // 创建文件输入流 // 文件二进制输入流 
           FileStream inputis = new FileStream(inputfile, FileMode.Open);
            if (filetype.Equals("xls"))
            {
                // 如果是Excel文件则创建HSSFWorkbook读取
                workbook = new HSSFWorkbook(inputis);
                // 设置Sheet数
                numOfSheets = workbook.NumberOfSheets;
            }
            else
            {
                throw new Exception("文件类型不支持");
            }
            //设置行头
            headHash = readLine();
        }

        // 函数readLine读取文件的一行
        public Hashtable readLine()
        {
            // 如果是XLS文件则通过POI提供的API读取文件
            if (filetype.Equals("xls"))
            {
                // 根据currSheet值获得当前的sheet
                ISheet sheet = workbook.GetSheetAt(currSheet);
                // 判断当前行是否到但前Sheet的结尾
                if (currPosition > sheet.LastRowNum)
                {
                    // 当前行位置清零
                    currPosition = 0;
                    // 判断是否还有Sheet
                    while (currSheet != numOfSheets - 1)
                    {
                        // 得到下一张Sheet
                        currSheet++;
                        sheet = workbook.GetSheetAt(currSheet);
                        // 当前行数是否已经到达文件末尾
                        if (currPosition == sheet.LastRowNum)
                        {
                            // 当前Sheet指向下一张Sheet
                            continue;
                        }
                        else
                        {
                            // 获取当前行数
                            int row = currPosition;
                            //设置行头
                            headHash.Clear();
                            headHash = getLine(sheet, row);
                            //读取第一列，其他，主要是外层循环起作用
                            currPosition++;
                            row = currPosition;
                            currPosition++;
                            // 读取当前行数据
                            return convertHash(headHash, getLine(sheet, row), columnsvalue, fieldsvalue);
                        }
                    }
                    return null;
                }
                // 获取当前行数
                int nowrow = currPosition;
                currPosition++;
                // 读取当前行数据
                return convertHash(headHash, getLine(sheet, nowrow), columnsvalue, fieldsvalue);
            }
            return null;
        }

        /**
	 * 
	 * @param hdata行头
	 * @param ddata数据信息
	 * @param columns列名称
	 * @param fileds列代码
	 * @return
	 */

        private Hashtable convertHash(Hashtable hdata, Hashtable ddata, String[] columns, String[] fileds)
        {
            Hashtable resultHash = new Hashtable();
            if (hdata.Count != 0)
            {
                String value = "";
                String key = "";
                for (int i = 0; i < ddata.Count; i++)
                {
                    value = ddata[i].ToString();
                    key = hdata[i].ToString();
                    key = fileds[getIndex(columns, key)];
                    resultHash.Add(key, value);
                }
            }
            else
            {
                resultHash = ddata;
            }
            return resultHash;
        }

        private int getIndex(String[] columns, String value)
        {
            int result = -1;
            int length = columns.Count();
            for (int i = 0; i < length; i++)
            {
                if (columns[i].Equals(value))
                {
                    result = i;
                    break;
                }
            }
            return result;
        }

        // 函数getLine返回Sheet的一行数据

        private Hashtable getLine(ISheet sheet, int row)
        {
            // 根据行数取得Sheet的一行
            IRow rowline = sheet.GetRow(row);
            // 创建字符创缓冲区
            //StringBuffer buffer = new StringBuffer();
            // 获取当前行的列数
            int filledColumns = rowline.LastCellNum;
            ICell cell = null;
            // 循环遍历所有列
            //在放入数据之前，先清除数据
            Hashtable dataHash = new Hashtable(); //数据HashMap
            dataHash.Clear();
            for (int i = 0; i < filledColumns; i++)
            {
                // 取得当前Cell
                cell = rowline.GetCell(i);
                String cellvalue = null;
                if (cell != null)
                {
                    // 判断当前Cell的Type
                    switch (cell.CellType)
                    {
                            // 如果当前Cell的Type为NUMERIC
                        case CellType.NUMERIC:
                            {
                                // 判断当前的cell是否为Date
                                if (DateUtil.IsCellDateFormatted(cell))
                                {
                                    // 如果是Date类型则，取得该Cell的Date值
                                    DateTime date = cell.DateCellValue;
                                    // 把Date转换成本地格式的字符串
                                    cellvalue = cell.DateCellValue.ToLocalTime().ToString();
                                }
                                    // 如果是纯数字
                                else
                                {
                                    // 取得当前Cell的数值
                                    double num = cell.NumericCellValue;
                                    DecimalFormat df = new DecimalFormat("###########");
                                    cellvalue = df.Format(num);
                                }
                                break;
                            }
                            // 如果当前Cell的Type为STRIN
                        case CellType.STRING:
                            // 取得当前的Cell字符串
                            cellvalue = cell.StringCellValue.Replace("'", "''");
                            break;
                            // 默认的Cell值
                        default:
                            cellvalue = " ";
                            break;
                    }
                }
                else
                {
                    cellvalue = "";
                }
                dataHash.Add(i, cellvalue); //将数据放入HashMap
            }
            // 以字符串返回该行的数据
            return dataHash;
        }

        static void Main(string[] args)
        {
            try
            {
                //String[] tmp = { "菜单ID", "菜单名称" };
                //String[] tmp1 = {"id", "name"};
                //var er = new ImportFromPoiExcel("E:/desktop/测试.xls", tmp, tmp1);
                //Hashtable line = er.readLine();
                //while (line != null)
                //{
                //    Console.WriteLine(line);
                //    line = er.readLine();
                //}
                //er.close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}
